﻿using System;
using System.Collections.ObjectModel;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Tibco.ServiceModel
{
    public sealed class TibcoBinding : Binding
    {
        long m_maxMessageSize;

        private CompositeDuplexBindingElement m_compositeDuplex;

        private TextMessageEncodingBindingElement m_encoding;

        private bool m_isInitialized;
        private ReliableSessionBindingElement m_session;

        private TransactionFlowBindingElement m_transactionFlow;

        private bool m_transactionsEnabled;

        private TibcoTransportBindingElement m_transport;

        public readonly static long DefaultMaxMessageSize = 8192L * 10;

        [ConfigurationProperty("deamon")]
        public string Deamon { get; set; }

        [ConfigurationProperty("service")]
        public string Service { get; set; }

        [ConfigurationProperty("network")]
        public string Network { get; set; }

        [ConfigurationProperty("dqName")]
        public string DQName { get; set; }

        [ConfigurationProperty("maxmessagesize")]
        public long MaxMessageSize
        {
            get
            {
                return this.m_maxMessageSize;
            }
            set
            {
                this.m_maxMessageSize = value;
            }
        }

        public bool OneWayOnly { get; set; }

        //public System.ServiceModel.ReliableSession ReliableSession
        //{
        //    get
        //    {
        //        return new System.ServiceModel.ReliableSession(this.m_session);
        //    }
        //}

        public override string Scheme
        {
            get
            {
                return "soap.tibco";
            }
        }

        public bool TransactionFlow
        {
            get
            {
                return this.m_transactionsEnabled;
            }
            set
            {
                this.m_transactionsEnabled = value;
            }
        }

        public TibcoTransportBindingElement Transport
        {
            get
            {
                return this.m_transport;
            }
        }

        public TibcoBinding(): this(DefaultMaxMessageSize)
        {
            base.Name = "TibcoBinding";
            base.Namespace = "http://schemas.Tibco.com/2007/Tibco/";

            this.Initialize();

            this.TransactionFlow = true;
        }

        public TibcoBinding(long maxMessageSize)
        {
            this.MaxMessageSize = maxMessageSize;
        }

        public TibcoBinding(string service, string network, string deamon, string dqName) : this(TibcoBinding.DefaultMaxMessageSize)
        {
            this.Deamon = deamon;
            this.Service = service;
            this.Network = network;
            this.DQName = dqName;
        }


        public override BindingElementCollection CreateBindingElements()
        {
            this.m_transport.Deamon = this.Deamon;
            this.m_transport.Service = this.Service;
            this.m_transport.Network = this.Network;
            this.m_transport.DQName = this.DQName;

            if (this.MaxMessageSize != DefaultMaxMessageSize)
            {
                this.m_transport.MaxReceivedMessageSize = this.MaxMessageSize;
            }
            BindingElementCollection bindingElementCollection = new BindingElementCollection();
            if (this.m_transactionsEnabled)
            {
                bindingElementCollection.Add(this.m_transactionFlow);
            }
            if (!this.OneWayOnly)
            {
                //bindingElementCollection.Add(this.m_session);
                //bindingElementCollection.Add(this.m_compositeDuplex);
            }
            bindingElementCollection.Add(this.m_encoding);
            bindingElementCollection.Add(this.m_transport);
            return bindingElementCollection;
        }

        private void Initialize()
        {
            lock (this)
            {
                if (!this.m_isInitialized)
                {
                    this.m_transport = new TibcoTransportBindingElement();
                    this.m_encoding = new TextMessageEncodingBindingElement();
                    this.m_session = new ReliableSessionBindingElement();
                    this.m_compositeDuplex = new CompositeDuplexBindingElement();
                    this.m_transactionFlow = new TransactionFlowBindingElement();
                    this.m_maxMessageSize = DefaultMaxMessageSize;
                    this.m_isInitialized = true;
                }
            }
        }
    }
}